<?php
/**
 *
 * @author ninetyseven.
 * @date 2023-03-29 0:12
 */

namespace App\Services;

use App\Enum\CardEnum;
use App\Enum\ScheduleEnum;
use App\Enum\CodeEnum;
use App\Enum\DriverEnum;
use App\Enum\LogsEnum;
use App\Enum\OrderDyplsEnum;
use App\Enum\OrderEnum;
use App\Enum\ThirdOrderEnum;
use App\Enum\TravelEnum;
use App\Enum\VillagerEnum;
use App\Enum\WalletsEnum;
use App\Http\Clients\ZccmzjgyxmClient;
use App\Models\AppraiseModel;
use App\Models\CmzjScheduleModel;
use App\Models\ConfigModel;
use App\Models\DriverCartModel;
use App\Models\DriverModel;
use App\Models\LogsModel;
use App\Models\OrderDyplsModel;
use App\Models\OrderExtendModel;
use App\Models\OrderModel;
use App\Models\OrdersAppealModel;
use App\Models\ThirdOrderAllModel;
use App\Models\UserCommunityModel;
use App\Models\VehicleConfigModel;
use App\Models\VillagerUserModel;
use App\Models\WalletModel;
use App\resources\Api\GetOrderListCollection;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Facades\DB;
use App\Services\Tools\HelpService;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class OrderService extends BaseService
{
    public const REDIS_DRIVER_ROD_ORDER_KEY = "driver:order:rod:%s";
    public static function addOrderChanged($orderIds)
    {
        $redis = app('redis.connection');

        if( !is_array($orderIds) ) $orderIds = [$orderIds];

        foreach( $orderIds as $orderId)
            $redis->rPush(ThirdOrderEnum::R_ORDER_CHANGE_FEEDBACK_KEY, $orderId);
    }

    /**
     * 订单信息回馈处理
     *
     * @param $orderId
     * @return void
     * @throws Exception
     */
    public static function orderChangeFeedback($orderId)
    {
        $selectFields = [
            'orders.order_no', 'orders.user_id','orders.driver_id',
            'orders.status as order_status',
            'orders.refund_fee',
            'orders.driver_id',
            'orders.transport_id',
            'orders.third_order_no',
            'd.driver_name',
            'd.phone as driver_phone',
            'oe.cart_type as car_type',
            'oe.cart_number as car_number',
            'oe.cart_color as car_color'
        ];
        try{
            $order = OrderModel::query()
                ->leftJoin('driver as d', 'orders.driver_id', '=', 'd.id')
                ->leftJoin("order_extend as oe", 'orders.id','=','oe.order_id')
                ->select($selectFields)
                ->find($orderId)->toArray();

            if(!empty($order)){
                // 字段转义
                $orderNo = $order['order_no'];              unset($order['order_no']);
                $thirdOrderNo = $order['third_order_no'];   unset($order['third_order_no']);
                $userId     = $order['user_id'];            unset($order['user_id']);
                $driverId   = $order['driver_id'];          unset($order['driver_id']);
                foreach(['driver_name','driver_phone'] as $field) $order[$field] = $order[$field] ?? "";

                $order['order_id'] = $orderId;

                // 将订单信息回馈到三方订单总表
                if( !empty($$thirdOrderNo) ) {
                    Log::notice(sprintf('回馈订单信息,ID=%d, order_no=%s, third_no=%s', $orderId, $orderNo, $thirdOrderNo));
                    ThirdOrderAllModel::query()->where(['order_no' => $orderNo, 'third_order_no' => $thirdOrderNo])->update($order);
                }

                // 清除缓存
                (new RedisKeysService())->deleteOrderListKey($userId,$driverId);
            }
        }catch (Exception|NotFoundExceptionInterface|ContainerExceptionInterface $e){
            throw new Exception(sprintf("订单回馈失败：订单ID（%d）.E=%s", $orderId,$e->getMessage()));
        }
    }

    /**
     * 统计司机待出行订单
     * @param int $userId
     * @return mixed
     * @author ninetyseven.
     * @date 2023-03-29 0:43
     */
    public static function getWaitOrderNum(int $userId = 0)
    {
        $where = [
            ['driver_id', '=', $userId],
            ['status', '=', OrderEnum::STATUS_PENDING_TRAVEL],
        ];
        return OrderModel::where($where)->count();
    }

    /**
     * 我的-统计服务订单数(司机)
     * @param int $userId
     * @return array
     * @author ninetyseven.
     * @date 2023-04-02 14:31
     */
    public static function getOrderDriverNum(int $userId = 0): array
    {
        $where = [
            ['driver_id', '=', $userId],
            ['status', '=', OrderEnum::STATUS_SUCCESS],
        ];

        //订单总数、服务公里数
        $result = DB::table('orders')
            ->select(
                DB::raw('COUNT(id) AS order_count'),
                DB::raw('SUM(distance) AS total_distance')
            )
            ->where($where)
            ->first();

        //村民
        $where[] = ['payment_method', '=', OrderEnum::ORDER_PAY_DIGITAL];
//        $villagesCount = OrderModel::where($where)->count();
        array_pop($where);

        //服务时长
        $result->service_time = OrderModel::query()->where($where)->sum('order_time');
        //时间转化为小时
        $result->service_time = $result->service_time > 0 ? number_format($result->service_time/60,1) : 0;

        //人次
        $orderCount = OrderModel::query()->where($where)->count();
        $where[] = ['is_accompany', '=', OrderEnum::ORDER_ACCOMPANY];
        $accompanyOrderCount = OrderModel::query()->where($where)->count();
        $peopleCount = $orderCount + $accompanyOrderCount;

        return [
            'order_count' => $result->order_count,//订单总数
            'service_people_count' => $peopleCount,//服务人次
//            'service_villages_count' => $villagesCount,//服务村民
            'service_villages_count' => $result->service_time,//服务时长
            'total_distance' =>  $result->total_distance > 0 ? bcdiv($result->total_distance, 1000) : 0,//服务公里数
        ];
    }

    /**
     * 首页-统计服务订单数(志愿者)
     * @param int $userId
     * @return array
     * @author ninetyseven.
     * @date 2023-04-15 15:25
     */
    public static function getOrderVolunteerNum(int $userId = 0): array
    {
        $where = [
            ['volunteer_id', '=', $userId],
            ['status', '=', OrderEnum::STATUS_SUCCESS],
        ];
        //订单总数、服务公里数
        $result = DB::table('orders')
            ->select(
                DB::raw('COUNT(id) AS order_count'),
                DB::raw('SUM(order_time) AS total_time'),
                DB::raw('SUM(distance) AS total_distance')
            )
            ->where($where)
            ->first();

        //村民
        $where[] = ['payment_method', '=', OrderEnum::ORDER_PAY_DIGITAL];
        $villagesCount = OrderModel::where($where)->count();

        return [
            'order_count' => $result->order_count,//订单总数
            'service_villages_count' => $villagesCount,//服务村民
            'total_time' => $result->total_time > 0 ? round($result->total_time/60) : 0,//服务时长
            'total_distance' => $result->total_distance > 0 ? round(bcdiv($result->total_distance, 1000)) : 0,//服务公里数
        ];
    }

    /**
     * 首页-订单列表
     * @param int $typeId
     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
     * @author ninetyseven.
     * @date 2023-03-30 23:08
     */
    public static function getIndexOrderList(int $typeId = 0, int $platformId = 0): \Illuminate\Http\Resources\Json\AnonymousResourceCollection
    {
        $where = [];
        if (!empty($typeId)) {
            $where[] = ['order_type', '=', $typeId];
        }
        $where[] = ['status', '=', OrderEnum::STATUS_PENDING_ORDER];
        $order = OrderModel::query()->where($where)
            ->orderBy('id', 'desc')
            ->paginate(HelpService::perPage());;
        return GetOrderListCollection::collection($order);
    }

    /**
     * @param $params
     * @return array|AnonymousResourceCollection
     * @throws Exception
     */
    public static function getMyOrderList($params){
        return self::_getMyOrderList($params['userId'], $params['typeId'], $params['platformId']);
    }
    /**
     * 获取订单列表
     *
     * @param int $userId
     * @param int $typeId
     * @param int $platformId
     * @return array|AnonymousResourceCollection
     * @throws Exception
     */
    private static function _getMyOrderList(int $userId = 0, int $typeId = 0, int $platformId = 0)
    {
        if (empty($userId)) {
            throw new Exception('用户id参数不存在');
        }
        $where = [];
        if (!empty($typeId)) {
            $where[] = ['status', '=', $typeId];
        }

        if ($platformId == TravelEnum::PLATFORM_DRIVER) {
            $model = OrderModel::query()
                ->where('activity_id', '=', 0)
                ->where('driver_id', $userId)->where($where);
            $sql = $model->toSql();
            $result = $model->orderBy('created_at', 'desc')
                ->paginate(HelpService::perPage())
                ->toArray();

            Log::notice(sprintf("FALSE LOG,pp=%d, sql=%s",HelpService::perPage(),$sql));
            if (!$result) {
                throw new Exception('没有待接单的订单');
            }
            Log::notice('FALSE LOG.=>'.var_export($result,true));

            return [
                'results' => self::format_order_fields($result),
                'platform_type' => TravelEnum::PLATFORM_DRIVER,
            ];
        } elseif ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $where[] = ['volunteer_id', '=', $userId];
            $where[] = ['platform_id', '=', $platformId];
        } else {
            $where[] = ['user_id', '=', $userId];
            $where[] = ['platform_id', '=', $platformId];
        }

        $obj = OrderModel::query()->where($where);
        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $obj->whereIn('status', [OrderEnum::STATUS_DRIVING, OrderEnum::STATUS_SUCCESS]);
        }

        $data = $obj->where('status', '!=', OrderEnum::STATUS_TIMEOUT)->orderBy('id', 'desc')
            ->paginate(HelpService::perPage());

        return GetOrderListCollection::collection($data);
    }
    public static function format_order_fields($result): array
    {
        // 获取车型和用车类型 20230810 by LC
        $vehicleType = ConfigModel::getVehicleType(); $vehicleType = json_decode($vehicleType, true);
        $vehicleUseType = ConfigModel::getVehicleUseType();$vehicleUseType = json_decode($vehicleUseType, true);

        $res = [];
        foreach ($result['data'] as $item) {
            $startLocation = $item['start_location'] ? explode(',', $item['start_location']) : [];
            $endLocation = $item['end_location'] ? explode(',', $item['end_location']) : [];
            $row = [
                'id' => $item['id'],
                'order_no' => $item['order_no'] ?? 0,
                'user_id' => $item['user_id'] ?? 0,
                'driver_id' => $item['driver_id'] ?? 0,
                'start_location' => $item['start_location'] ?? '',
                'start_location_x' => !empty($startLocation) ? $startLocation[0] : 0,
                'start_location_y' => !empty($startLocation) ? $startLocation[1] : 0,
                'end_location' => $item['end_location'] ?? '',
                'end_location_x' => !empty($endLocation) ? $endLocation[0] : 0,
                'end_location_y' => !empty($endLocation) ? $endLocation[1] : 0,
                'start_time' => $item['start_time'] ? date('Y-m-d H:i:s', $item['start_time']) : 0,
                'end_time' => $item['end_time'] ? date('Y-m-d H:i:s', $item['end_time']) : 0,
                'created_at' => $item['created_at'] ,
                'start_address' => $item['start_address'] ?? '',
                'start_address_detail' => $item['start_address_detail'] ?? '',
                'end_address' => $item['end_address'] ?? '',
                'end_address_detail' => $item['end_address_detail'] ?? '',
                'distance' => $item['distance'] ? ($item['distance'] / 1000) : 0,
                'amount' => $item['amount'] ? number_format($item['amount'], 2) : '',
                'platform_id' => $item['platform_id'] ?? '',
                'platform_type' => isset($item['platform_id']) ? TravelEnum::APP_PLATFORM_NAMES[$item['platform_id']] : '',
                'order_type' => $item['order_type'] ?? 1,
                'is_accompany' => $item['is_accompany'] ?? 0,
                'payment_method' => $item['payment_method'] ?? 0,
                'payment_method_name' => OrderEnum::AMOUNT_UNIT[$item['payment_method']] ?? '-',
                'status' => $item['status'],
                'status_name' => OrderEnum::STATUS_NAME[$item['status']],
                'vehicle_type_name' => $vehicleType[$item['vehicle_type']] ?? '-',
                'vehicle_use_type_name' => $vehicleUseType[$item['vehicle_use_type']] ?? '-',
                'vehicle_use_type_name_with_flight_no'=> $vehicleUseType[$item['vehicle_use_type']].( empty($item['flight_no'])?'':'，航班号：'.$item['flight_no'] ),
            ];
            $res[] = $row;
        }
        return $res;
    }

    /**
     * 居委会/村委会-订单列表
     * getCommunityList
     * @param int $userId
     * @param int $typeId
     * @param int $platformId
     * @return AnonymousResourceCollection
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/3
     */
    public static function getCommunityList(int $userId = 0, int $typeId = 0, int $platformId = 0): AnonymousResourceCollection
    {
        if (empty($platformId)) {
            throw new Exception('参数不正确');
        }

        $where = [];
        $where[] = ['user_id', '=', $userId];
        $where[] = ['user_type', '=', $platformId];

        $userCommunity = UserCommunityModel::query()->where($where)->get();
        if (!$userCommunity) {
            throw new Exception('暂无数据');
        }
        //先得到当前登录人的所有小区
        $communityIds = $userCommunity->pluck('community_id')->toArray();
        $res = UserCommunityModel::query()->whereIn('community_id', $communityIds)->get();
        //得到所有的用户id
        $userIds = array_unique($res->pluck('user_id')->toArray());

        //订单
        $obj = OrderModel::query()->whereIn('user_id', $userIds);
        if (!empty($typeId)) {
            $obj->where('status', '=', $typeId);
        }
        $obj->where('platform_id', '!=', TravelEnum::PLATFORM_DONATION);
        $data = $obj->orderBy('id', 'desc')
            ->paginate(HelpService::perPage());
        return GetOrderListCollection::collection($data);
    }

    /**
     * 创建订单
     * @param Request $request
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-03-29 23:42
     */
    public static function addOrder(Request $request, int $platformId = 0)
    {
        if (empty($request->start_address)) {       throw new Exception('起点地址不能为空：start_address');      }
        if (empty($request->start_location)) {      throw new Exception('起点位置不能为空：start_location');     }
        if (empty($request->end_address)) {         throw new Exception('终点地址不能为空：end_address');        }
        if (empty($request->end_location)) {        throw new Exception('终点位置不能为空：end_location');       }
        if (empty($request->start_time)) {          throw new Exception('出发时间不能为空：start_time');         }
        if (empty($request->distance)) {            throw new Exception('行驶距离（单位：米）：distance');        }
//        if (empty($request->amount)) {              throw new Exception('金额不能为空：amount');                }
        if (empty($request->payment)) {             throw new Exception('支付方式不能为空：payment');            }
        if (empty($request->vehicle_type)) {             throw new Exception('车型不能为空：vehicle_type');            }
        if (empty($request->vehicle_use_type)) {             throw new Exception('用车类型不能为空：vehicle_use_type');            }
        if (empty($request->duration)) {             throw new Exception('时长不能为空：duration');            }
        if (!in_array($request->payment,array_keys(OrderEnum::ORDER_PAY_KEYS))) {   throw new Exception('支付方式非法：payment');}

        // 等到降级的城市 code
        $cityCode = parent::cityCodeDown($request->city);

        $payment = OrderEnum::ORDER_PAY_KEYS[$request->payment];
        // TODO 往返订单金额的扣除情况
        $request->amount = VehicleConfigService::amount($cityCode,$request->distance, $request->vehicle_use_type, $request->vehicle_type, $payment);

        $reason = $request->is_accompany != OrderEnum::ORDER_ACCOMPANY ? $request->reason ? $request->reason : '' : '';
        $isOneWay = $request->is_one_way ?? 1;

        if ($isOneWay == 2 && empty($request->departure_time)) {
            throw new Exception('往返出发时间不能为空：departure_time');
        }
        // 获取用户信息 提前到这
        $userinfo = VillagerUserModel::query()->where('id', $request->userId)->first();
        if (!$userinfo) {
            throw new Exception('用户不存在');
        }
        $paymentMethod = $amountType = $payment;
//        // 根据人员身份来确定支付方式和钱的方式
//        if ($platformId == TravelEnum::PLATFORM_DONATION) {
//            $paymentMethod = OrderEnum::ORDER_PAY_INTEGRAL;
//            $amountType     = OrderEnum::ORDER_PAY_INTEGRAL;
//        } else {
//            $paymentMethod = OrderEnum::ORDER_PAY_DIGITAL;
//            $amountType     = OrderEnum::ORDER_PAY_DIGITAL;
//        }
        $orderDataBase = [
            'user_id' => $request->userId,                      'user_phone'    => $userinfo->phone,
            'platform_id' => $platformId,                   'vehicle_use_type'  => $request->vehicle_use_type,
            'vehicle_type'      =>$request->vehicle_type,       'distance' => $request->distance,
            'is_return' => $isOneWay,                           'flight_no' => $request->flight_no ?? '',
            'amount' => $request->amount,                       'is_accompany' => $request->is_accompany ?? 0,
            'is_monitor' => $request->is_monitor ?? 0,          'reason' => $reason,
            'volunteer_sex' => $request->volunteer_sex ?? 0,    'payment_method'    => $paymentMethod,
            'amount_type'       => $amountType,                 'duration' => $request->duration,
            'city_code' => $cityCode
        ];
        DB::beginTransaction();
        // 创建 去单
        $orderData = [
            'order_no' => HelpService::createOrderNum(),                'start_address' => $request->start_address,
            'start_address_detail' => $request->start_address_detail,   'start_location' => $request->start_location,
            'end_address' => $request->end_address,                     'end_address_detail' => $request->end_address_detail,
            'end_location' => $request->end_location,                   'start_time' => strtotime($request->start_time),
            'start_adcode'  => $request->start_adcode,                  'end_adcode'    => $request->end_adcode,
        ];
        $orderData = array_merge($orderDataBase, $orderData);

        $orderInfo = OrderModel::create($orderData);
        if (!$orderInfo) {
            DB::rollBack();
            throw new Exception('创建订单失败');
        }
//        Log::info($orderInfo);
        // 创建返单
        if ($isOneWay == 2) {
            $orderData = [
                'order_no' => HelpService::createOrderNum(),                'start_address' => $request->end_address,
                'start_address_detail' => $request->end_address_detail,     'start_location' => $request->end_location,
                'end_address' => $request->start_address,                   'end_address_detail' => $request->start_address_detail,
                'end_location' => $request->start_location,                 'start_time' => strtotime($request->departure_time),
                'go_order_id'   => $orderInfo->id,
                'start_adcode'  => $request->end_adcode,                    'end_adcode'    => $request->start_adcode,
            ];
            $orderData = array_merge($orderDataBase, $orderData);

            $returnOrderInfo = OrderModel::query()->create($orderData);
            if (!$returnOrderInfo) {
                DB::rollBack();
                throw new Exception('回程订单创建失败');
            }
        }
        DB::commit();

        return $orderInfo;
    }

    /**
     * 扣除数字人民币
     * @param $userInfo
     * @param $orderInfo
     * @return void
     * @throws Exception
     */
    public static function _deductDigital($orderInfo)
    {
        //查询用户钱包
        $userWhere = [
            'user_id' => $orderInfo->user_id,
            'user_type' => WalletsEnum::WALLET_USER_VILLAGER
        ];
        $userWallet = WalletModel::query()->where($userWhere)->first();
        if (!$userWallet) {
            throw new Exception('用户钱包不存在');
        }

        //数字人民币
        if ($userWallet->digital_balance - $orderInfo->amount < 0) {
            throw new Exception('余额不足');
        }

        $userWallet->digital_balance = $userWallet->digital_balance - $orderInfo->amount;
        if (!$userWallet->save()) {
            throw new Exception('扣除用户余额失败');
        }
    }

    /**
     * 扣除积分
     * @param $userInfo
     * @param $orderInfo
     * @return void
     * @throws Exception
     */
    public static function _deductPoint($orderInfo)
    {
        $score = (new ZccmzjgyxmClient())->getUserConsume($orderInfo->user_phone);
        if ($score['code'] != CodeEnum::SUCCESS) {
            throw new Exception('积分:'.$score['msg'], CodeEnum::POINT_NOT_ENOUGH);
        }
        $score = $score['data']['score'];

        if ($score < $orderInfo->amount) {
            throw new Exception('用户积分不足');
        }
        $products = sprintf('下单时间%s：从%s，到%s。',date('Y-m-d H:i:s'), $orderInfo->start_address, $orderInfo->end_address);

        $res = (new ZccmzjgyxmClient())->consumeCredits($orderInfo->user_phone, $orderInfo->order_no, $orderInfo->amount, $products);
        if ($res['code'] != CodeEnum::SUCCESS) {
            throw new Exception($score['msg']);
        }
    }

    /**
     * 添加支付log
     *
     * @param $orderInfo
     * @param $comment
     * @return int
     * @throws Exception
     */
    public static function _addAmountLogPay($orderInfo, $comment): int
    {
        $logData = [
            'order_no' => $orderInfo->order_no,
            'user_id' => $orderInfo->user_id,
            'driver_id' => !empty($order['driver_id']) ? $order['driver_id'] : 0,
            'user_type' => WalletsEnum::WALLET_USER_VILLAGER,
            'amount' => $orderInfo->amount,
            'amount_type'=> $orderInfo->amount_type,
            'change_type' => WalletsEnum::WALLET_LOG_TYPE_OUT,
            'comment' => $comment,
            'start_address' => $orderInfo->start_address,
            'end_address' => $orderInfo->end_address,
            'start_time' => $orderInfo->start_time,
        ];

        return CommonService::recordAmountLog($logData);
    }

    /**
     * 出行积分支付
     * @param $orderInfo
     * @return true
     * @throws Exception
     */
    public static function _decuteGycxAxd($orderInfo)
    {
        try {
            $orderInfo = OrderModel::query()->find($orderInfo->id); //从DB重新获取订单信息

            $wallet = WalletModel::query()->where(['user_id' => $orderInfo->user_id, 'user_type' => WalletsEnum::WALLET_USER_VILLAGER])->select(['id', 'user_id', 'user_type', 'gycx_axd'])->first();

            if (empty($wallet)) {

                $msg = '钱包不存在';
            } elseif ($wallet->gycx_axd < $orderInfo->amount) {

                $msg = CardEnum::CARD_VALUE_UNIT[$orderInfo->amount_type] . '不足，支付失败';

            } else {

                $wallet->decrement('gycx_axd', $orderInfo->amount);
                $msg = true;
            }
            if( !($msg === true ) ){
                throw new Exception($msg);
            }
            return true;
        }catch ( Exception $e ) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * @throws Exception
     */
    public static function _decuteCommuteAxd($orderInfo)
    {
        try {
            $orderInfo = OrderModel::query()->find($orderInfo->id); //从DB重新获取订单信息

            return EnterpriseCommuteService::paySxcxOrder($orderInfo);
        }catch (Exception $e){
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 金额计算
     * @param int $kmNum
     * @param bool $flag
     * @return float
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-03 23:42
     * 13289
     */
    public static function amount(int $kmNum = 0,bool $flag = false)
    {
        throw new Exception('此方法已经废除');
        /*
        if (empty($kmNum)) {
            throw new Exception('公里数不能为空');
        }
        //米转化成公里， 13.289
        $kmNum = $kmNum / 1000;
        $priceKm = OrderEnum::PRICE_KM_NUM;
        //69.01
        // 系数
        $ratio = OrderEnum::PRICE_KM_RATIO;
        if ($flag) {
            $ratio = OrderEnum::PRICE_TRAVEL_KM_RATIO;
        }
        $amount = round($kmNum * $priceKm * $ratio, 2);
        if ( OrderEnum::PRICE_PRECISE_INT ){
            if ( OrderEnum::PRICE_PRECISE_CEIL ) $amount = ceil($amount);
            else $amount = floor($amount);
        }

        return $amount;
        */
    }

    /**
     * 获取订单详情
     * @param int $orderId
     * @param bool $isWhere
     * @param int $orderType
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-05 13:14
     */
    public static function getOrderInfo(int $orderId = 0, bool $isWhere = false, int $orderType = 1, int $platformId = 0): array
    {
        $where = [];
        if ($isWhere) {
            $where[] = ['order_type', '=', $orderType];
        }

        $orderInfo = OrderModel::query()->where($where)->find($orderId);
        if (!$orderInfo) {
            throw new Exception('订单不存在');
        }

//      使用hasOne方法取得订单的
        $oe = $orderInfo->oe;

        $orderInfo = $orderInfo->toArray();
        if( isset($orderInfo['oe'])){
            unset($orderInfo['oe']);
            $oe=$oe->toArray();
            foreach( ['cart_type','cart_color','cart_number'] as $field) $orderInfo[$field] = $oe[$field] ?? '-';
            $recordRule = VehicleConfigService::_formatAmountAndRule(json_decode($oe['amount_rule'],true), $orderInfo['distance']);
            $orderInfo['calculate_rule']    = $recordRule['rule'];
            $orderInfo['travel_amount']     = $recordRule['amount'];
        }

        $orderInfo['appraise'] = AppraiseModel::query()->where('order_id', $orderInfo['id'])->select('appraise', 'words_appraise','label_tag')->first();;
        $orderInfo['is_modify'] = !empty($orderInfo['modify_address']);

        $appealInfo = OrdersAppealModel::query()->where('order_id', $orderInfo['id'])->select('abnormal_images', 'abnormal_reasons')->first();
        if ($appealInfo) {
            $appealInfo = $appealInfo->toArray();
            $images = explode(',', $appealInfo['abnormal_images']);
            $arr = [];
            foreach ($images as $image) {
                $arr[] = env('OSS_URL') . $image;
            }
            $appealInfo['abnormal_images'] = $arr;
        }

        $orderInfo['appeal_data'] = !empty($appealInfo) ? $appealInfo : (object)[];
        $orderInfo['start_time_full'] = isset($orderInfo['start_time']) ? date('Y/m/d H:i:s', $orderInfo['start_time']) : 0;
        $orderInfo['start_time'] = isset($orderInfo['start_time']) ? date('m-d H:i', $orderInfo['start_time']) : 0;
        $orderInfo['end_time'] = isset($orderInfo['end_time']) ? date('m-d H:i', $orderInfo['end_time']) : 0;
        // 陪同人员
        if ($orderInfo['is_accompany'] == OrderEnum::ORDER_ACCOMPANY) {
            $orderInfo['accompany_data'] = VillagerUserModel::query()->where('id', $orderInfo['volunteer_id'])->first();
        } else {
            $orderInfo['accompany_data'] = (object)[];
        }
        // 用车类型
        $vehicleType = ConfigModel::getVehicleType(); $vehicleType = json_decode($vehicleType, true);
        $vehicleUseType = ConfigModel::getVehicleUseType();$vehicleUseType = json_decode($vehicleUseType, true);

        $orderInfo['vehicle_type_name'] = $vehicleType[$orderInfo['vehicle_type']];
        $orderInfo['vehicle_use_type_name'] = $vehicleUseType[$orderInfo['vehicle_use_type']];

        // 虚拟号 20230925 by LC
        if( env('ALIYUN_DYPLS_ENABLED',true) )
            $virtualPhone = OrderDyplsModel::query()->where(['order_no'=>$orderInfo['order_no'],'status'=>OrderDyplsEnum::STATUS_BIND_SUCCESS])->value('phone_x');


        $user = VillagerUserModel::query()->where('id', $orderInfo['user_id'])->select(['id','real_name','nick_name','phone','avatar'])->first();

        $user['real_phone'] = $user['phone'];
        // 将虚拟号给到终端 20230925 by LC
        $user['virtual_phone'] = empty($virtualPhone)?$user['phone']:$virtualPhone;
        $user['phone'] = empty($virtualPhone)?$user['phone']:$virtualPhone;


        // 司机
        $driver = DriverModel::query()->where('id', $orderInfo['driver_id'])->select(['id','driver_name','head_img','phone','gender'])->first();
        // 司机接单数
        $driver['order_total_num'] = OrderModel::query()->where('driver_id', $orderInfo['driver_id'])->count();

        // 如果已经绑定司机
        if( !empty($orderInfo['driver_id']) ){
            // 将虚拟号给到终端 20230925 by LC
            $driver['virtual_phone'] = empty($virtualPhone)?$driver['phone']:$virtualPhone;
        }

        // 司机整体评价
        // 获取司机所有的订单评分
        $orderAppraiseData = AppraiseModel::query()->where('driver_id', $orderInfo['driver_id'])->avg('appraise');
        $driver['score'] = round($orderAppraiseData) ;

        //村民
        $orderInfo['user'] = $user;
        $orderInfo['driver'] = $driver;

        // 变更订单状态
        $orderInfo['status'] = $orderInfo['status'] != OrderEnum::STATUS_PICKUP_ARRIVED ? $orderInfo['status'] : OrderEnum::STATUS_PENDING_TRAVEL;

        //碳排排放出行距离*0.95向上取整
        $orderInfo['carbon_emission'] = ceil(($orderInfo['distance'] / 1000) * 0.95);
        $orderInfo['current_time']  = date('Y/m/d H:i:s');

        return $orderInfo;
    }

    /**
     * 修改订单
     * @param Request $request
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-03-29 23:42
     */
    public static function updateOrder(Request $request)
    {
        throw new Exception('此方法已经废除。');
        /*
        if (empty($request->id)) {
            throw new Exception('订单id不能为空：id');
        }
        if (empty($request->modify_address)) {
            throw new Exception('修改地址不能为空：modify_address');
        }
        if (empty($request->modify_location)) {
            throw new Exception('修改地点位置不能为空：modify_location');
        }
        if (empty($request->end_address)) {
            throw new Exception('终点地址不能为空：end_address');
        }
        if (empty($request->end_location)) {
            throw new Exception('终点位置不能为空：end_location');
        }

        //修改订单时检查金额,如果金额不够则需判断用户是否有足够的余额，有余额则扣除余额，没有则提示用户充值
        $orderInfo = OrderModel::query()->where('id', $request->id)->first();
        if (!$orderInfo) {
            throw new Exception('订单不存在');
        }

        //订单金额
        $orderAmount = $orderInfo->amount;
        //计算修改地址后的订单金额
        // 启用新的里程规则
//        $amount = self::amount($request->km_num);
        $amount = VehicleConfigService::amount($request->km_num, $request->vehicle_use_type, $request->vehicle_type);


        //修改订单
        $data = [
            'modify_address' => $request->modify_address,
            'modify_location' => $request->modify_location,
            'end_address' => $request->end_address,
            'end_location' => $request->end_location,
            'amount' => $amount,
            'updated_at' => time()
        ];
        // 订单金额大于修改后的金额，退还差价
        $diffAmount = $orderAmount - $amount;
        if ($diffAmount > 0) {
            //退还差价
            $data['estimate_type'] = OrderEnum::ORDER_ESTIMATE_PLUS;
            $data['estimate_money'] = $diffAmount;
        } else {
            $diffAmount = abs($diffAmount);
            //扣除差价
            $userWallet = WalletModel::query()
                ->where('user_id', $orderInfo->user_id)
                ->where('user_type', WalletsEnum::WALLET_USER_VILLAGER)
                ->first();
            if (!$userWallet) {
                throw new Exception('用户钱包不存在');
            }

            if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_DIGITAL) {
                //判断用户数字人民币是否足够
                if ($userWallet->digital_balance < $diffAmount) {
                    throw new Exception('用户数字人民币不足');
                }
            } else {
                $userinfo = VillagerUserModel::query()->where('id', $orderInfo->user_id)->first();
                if (!$userinfo) {
                    throw new Exception('用户不存在');
                }

                //判断用户积分是否足够
                $score = (new ZccmzjgyxmClient())->getUserConsume($userinfo->phone);
                if ($score['code'] != CodeEnum::SUCCESS) {
                    throw new Exception($score['msg']);
                }
                $score = $score['data']['score'];

                if ($score < $diffAmount) {
                    throw new Exception('用户积分不足');
                }

                $res = (new ZccmzjgyxmClient())->consumeCredits($userinfo->phone, $orderInfo->order_no, $diffAmount);
                if ($res['code'] != CodeEnum::SUCCESS) {
                    throw new Exception($score['msg']);
                }
            }
            //直接补差价
            $data['amount'] = intval(abs($diffAmount));
        }

        return OrderModel::where([
            "id" => $request->id,
        ])->update($data);
        */
    }

    /**
     * 评价
     * @param Request $request
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-05
     */
    public static function appraiseOrder(Request $request)
    {
        if (empty($request->userId)) {
            throw new Exception('用户id参数不存在');
        }

        $order = OrderModel::query()->where('id', $request->order_id)->first();
        if (!$order) {
            throw new Exception('订单不存在');
        }

        //判断是否已经评价过
        $appraise = AppraiseModel::query()->where('order_id', $request->order_id)->first();
        if ($appraise) {
            throw new Exception('已经评价过了');
        }

        $data = [
            'order_id' => $request->order_id,
            'user_id' => $request->userId,
            'appraise' => !empty($request->appraise) ? $request->appraise : '',
            'label_tag' => !empty($request->label_tag) ? $request->label_tag : '',
            'driver_id' => $order->driver_id,
            'words_appraise' => !empty($request->words_appraise) ? $request->words_appraise : '',
        ];
        return AppraiseModel::query()->create($data);
    }


    /**
     * 更新订单状态(司机)
     * @param array $params
     * @param int $orderId
     * @return bool
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-05 13:15
     */
    public static function updateOrderStatus(array $params = [], int $orderId = 0): bool
    {
        if (!$orderId) {
            throw new Exception('订单id不存在');
        }
        $orderInfo = OrderModel::query()->find($orderId);
        if (!$orderInfo) {
            throw new Exception('订单信息不存在');
        }

        $res = OrderModel::query()->where('id', $orderId)->update($params);
        if (!$res) {
            throw new Exception('订单更新失败不存在');
        }

        return true;
    }

    /**
     * 预计扣除
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-05 13:14
     */
    public static function expectedDeduction(Request $request, $payment): array
    {
        $result = WalletModel::query()->select('point_balance', 'digital_balance', 'gycx_axd')->where(
            ['user_type' => WalletsEnum::WALLET_USER_VILLAGER, 'user_id' => $request->userId]
        )->first();

        if (!$result) {
            throw new Exception('用户钱包信息不存在');
        }
        $result = $result->toArray();

        $cityCode = parent::cityCodeDown($request->city_code);

        // 取消原预计扣款金额 20230809 by LC
        $amountAndRule = VehicleConfigService::amountAndRule($cityCode,$request->km_num, $request->vehicle_use_type, $request->vehicle_type, $payment);
        $result['expected'] = $amountAndRule['amount'];
        $result['calculate_rule'] = $amountAndRule['rule'];
        return $result;
    }

    /**
     * 获取订单列表
     * getInfo
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/4/30
     */
    public static function getInfo(): array
    {
        $res = OrderModel::query()->where('volunteer_id', request()->userId)->where('status', OrderEnum::STATUS_DRIVING)->first();
        if (!$res) {
            throw new Exception('没有正在进行中的订单');
        }

        return $res->toArray();
    }

    /**
     * 取消订单
     * @param array $params
     * @param int $orderId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model
     * @throws GuzzleException
     */
    public static function cancelOrderStatus(int $orderId = 0)
    {

        if (!$orderId) {
            throw new Exception('订单id不存在');
        }
        $orderInfo = OrderModel::query()->find($orderId);
        if (!$orderInfo) {
            throw new Exception('订单信息不存在');
        }
        //订单状态进行中,已完成不允许取消
        if ($orderInfo->status == OrderEnum::STATUS_DRIVING || $orderInfo->status == OrderEnum::STATUS_SUCCESS) {
            throw new Exception('订单状态不允许取消');
        }
        $orderInfo->old_status = $orderInfo->status;

        $money = $orderInfo->amount;
        $params['amount'] = $money;
        $params['status'] = OrderEnum::STATUS_CANCEL;
        $amountUnit = OrderEnum::AMOUNT_UNIT[$orderInfo->amount_type];

        $deductMoney = 0;
        $returnMoney = $money;
        // OrderEnum::ORDER_DEDUCT_ORDER_POINTS_MINUTES分钟内，扣一定的积分
        if( $orderInfo->start_time - time()  < OrderEnum::ORDER_DEDUCT_ORDER_POINTS_MINUTES * 60 ) {
            $deductMoney = ceil($money * OrderEnum::ORDER_DEDUCT_ORDER_POINTS_RATIO);
            $returnMoney = $money - $deductMoney;
        }elseif( $orderInfo->start_time - time()  < OrderEnum::ORDER_DEDUCT_ORDER_POINTS_MINUTES2 * 60 ) {
            $deductMoney = ceil($money * OrderEnum::ORDER_DEDUCT_ORDER_POINTS_RATIO2);
            $returnMoney = $money - $deductMoney;
        }
        if( $deductMoney > 0 )$params['deduct_amount'] = $deductMoney;

        $returnMoney = intval($returnMoney); // 确保 退款数字为整数
        //如果需要 返还
        if ( $returnMoney > 0) {
            $logContent = '取消订单返还部分' . $amountUnit . '。返还：' . $returnMoney;
            // 数字钱包 或 出行积分
            if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_DIGITAL
                || $orderInfo->amount_type == OrderEnum::ORDER_PAY_GYCX_AXD)
            {
                $wallet = WalletModel::query()->where('user_id', $orderInfo->user_id)->where('user_type', WalletsEnum::WALLET_USER_VILLAGER)->first();
                if (!$wallet) {
                    throw new Exception('用户钱包信息不存在');
                }
                if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_DIGITAL) $wallet->digital_balance = $wallet->digital_balance + $returnMoney;
                if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_GYCX_AXD) $wallet->gycx_axd = $wallet->gycx_axd + $returnMoney;

                $wallet->save();

            } elseif ($orderInfo->amount_type == OrderEnum::ORDER_PAY_INTEGRAL ) { // 公益诚信积分
                $res = (new ZccmzjgyxmClient())->returnCredits($orderInfo->user_phone, $orderInfo->order_no, $returnMoney);
                if ($res['code'] != CodeEnum::SUCCESS) {
                    throw new Exception($amountUnit . '：' . $res['msg']);
                }
            } elseif ($orderInfo->amount_type == OrderEnum::ORDER_PAY_ENTERPRISE_COMMUTE_10W ) { // 企业员工 通勤
                $result = EnterpriseCommuteService::cancelSxcxOrder($orderInfo, $returnMoney);
                if( !($result === true)){
                    throw new Exception($amountUnit . '：' . $result['msg']);
                }
            }
            //记录返还日志
            CommonService::recordAmountLog([
                'order_no' => $orderInfo->order_no,
                'user_id' => $orderInfo->user_id,
                'driver_id' => !empty($order['driver_id']) ? $order['driver_id'] : 0,
                'user_type' => WalletsEnum::WALLET_USER_VILLAGER,
                'amount' => $returnMoney,
                'amount_type' => $orderInfo->amount_type,
                'change_type' => WalletsEnum::WALLET_LOG_TYPE_IN,
                'comment' => $logContent,
                'start_address' => $orderInfo->start_address,
                'end_address' => $orderInfo->end_address,
                'end_time' => $orderInfo->end_time,
                'start_time' => $orderInfo->start_time,
            ]);
        }

        $res = OrderModel::query()->where('id', $orderId)->update($params);
        if (!$res) {
            throw new Exception('取消订单失败');
        }

        return $orderInfo;
    }


    /**
     * 等待接单列表
     *
     * @param int $userId
     * @return array[]
     * @throws Exception
     */
    public static function getWaitOrderList(int $userId = 0)
    {
        if (!$userId) {
            throw new Exception('用户id不存在');
        }
        $platformId = self::getPlatformId();

        if ($platformId != TravelEnum::PLATFORM_DRIVER) {
            throw new Exception('平台id错误');
        }

        $result = OrderModel::query()
            ->where('driver_id', $userId)
            ->whereIn('status', [OrderEnum::STATUS_PENDING_TRAVEL,OrderEnum::STATUS_PICKUP_START,OrderEnum::STATUS_PICKUP_ARRIVED])
            ->orderBy('created_at', 'desc')
            ->paginate(HelpService::perPage())->toArray();

        if (!$result) {
            throw new Exception('没有待接单的订单');
        }
        $vehicleType = ConfigModel::getVehicleType(); $vehicleType = json_decode($vehicleType, true);
        $vehicleUseType = ConfigModel::getVehicleUseType();$vehicleUseType = json_decode($vehicleUseType, true);

        $res = [];
        foreach ($result['data'] as $item) {
            $startLocation = $item['start_location'] ? explode(',', $item['start_location']) : [];
            $endLocation = $item['end_location'] ? explode(',', $item['end_location']) : [];
            $row = [
                'id' => $item['id'],
                'order_no' => $item['order_no'] ?? 0,
                'user_id' => $item['user_id'] ?? 0,
                'driver_id' => $item['driver_id'] ?? 0,
                'start_location' => $item['start_location'] ?? '',
                'start_location_x' => !empty($startLocation) ? $startLocation[0] : 0,
                'start_location_y' => !empty($startLocation) ? $startLocation[1] : 0,
                'end_location' => $item['end_location'] ?? '',
                'end_location_x' => !empty($endLocation) ? $endLocation[0] : 0,
                'end_location_y' => !empty($endLocation) ? $endLocation[1] : 0,
                'start_time' => $item['start_time'] ? date('Y-m-d H:i:s', $item['start_time']) : 0,
                'end_time' => $item['end_time'] ? date('Y-m-d H:i:s', $item['end_time']) : 0,
                'start_address' => $item['start_address'] ?? '',
                'start_address_detail' => $item['start_address_detail'] ?? '',
                'end_address' => $item['end_address'] ?? '',
                'end_address_detail' => $item['end_address_detail'] ?? '',
                'distance' => $item['distance'] ? ($item['distance'] / 1000) : 0,
                'amount' => $item['amount'] ? number_format($item['amount'], 2) : '',
                'platform_id' => $item['platform_id'] ?? '',
                'platform_type' => isset($item['platform_id']) ? TravelEnum::APP_PLATFORM_NAMES[$item['platform_id']] : '',
                'order_type' => $item['order_type'] ?? 1,
                'is_accompany' => $item['is_accompany'] ?? 0,
                'payment_method' => $item['payment_method'] ?? 0,
                'payment_method_name' => $item['payment_method'] == 1 ? '数字人民币' : '积分',
                'status' => $item['status'],
                'status_name' => OrderEnum::STATUS_NAME[$item['status']],
                'vehicle_use_type'=> $item['vehicle_use_type'],
                'vehicle_type'=> $item['vehicle_type'],
                'vehicle_use_type_name'=> $vehicleUseType[$item['vehicle_use_type']],
                'vehicle_type_name'=> $vehicleType[$item['vehicle_type']],
                'vehicle_use_type_name_with_flight_no'=> $vehicleUseType[$item['vehicle_use_type']].( empty($item['flight_no'])?'':'，航班号：'.$item['flight_no'] ),
            ];
            $res[] = $row;
        }
        return [
            'results' => $res,
        ];
    }

    /**
     *
     * checkOrder
     * @param Request $request
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/9
     */
    public static function checkOrder(Request $request): array
    {
        throw new Exception('此方法已经作废.Since 2023 11 13');
        /*
        if (empty($request->id)) {
            throw new Exception('订单id不能为空：id');
        }
        if (empty($request->modify_address)) {
            throw new Exception('修改地址不能为空：modify_address');
        }
        if (empty($request->modify_location)) {
            throw new Exception('修改地点位置不能为空：modify_location');
        }
        if (empty($request->end_address)) {
            throw new Exception('终点地址不能为空：end_address');
        }
        if (empty($request->end_location)) {
            throw new Exception('终点位置不能为空：end_location');
        }


        //修改订单时检查金额,如果金额不够则需判断用户是否有足够的余额，有余额则扣除余额，没有则提示用户充值
        $orderInfo = OrderModel::query()->where('id', $request->id)->first();
        if (!$orderInfo) {
            throw new Exception('订单不存在');
        }

        //订单金额
        $orderAmount = $orderInfo->amount;
        //计算修改地址后的订单金额
        $amount = VehicleConfigService::amount($request->km_num, $request->vehicle_use_type, $request->vehicle_type);



        // 订单金额大于修改后的金额，退还差价
        $diffAmount = $orderAmount - $amount;
        if ($diffAmount > 0) {
            //退还差价
            $estimateType = OrderEnum::ORDER_ESTIMATE_PLUS;
        } else {
            //扣除差价
            $estimateType = OrderEnum::ORDER_ESTIMATE_REDUCE;

            $userWallet = WalletModel::query()
                ->where('user_id', $orderInfo->user_id)
                ->where('user_type', WalletsEnum::WALLET_USER_VILLAGER)
                ->first();
            if (!$userWallet) {
                throw new Exception('用户钱包不存在');
            }

            if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_DIGITAL) {
                //判断用户数字人民币是否足够
                if ($userWallet->digital_balance < abs($diffAmount)) {
                    throw new Exception('用户数字人民币不足');
                }
            } else {
                $userInfo = VillagerUserModel::query()->where('id', $orderInfo->user_id)->first();
                if (!$userInfo) {
                    throw new Exception('用户信息不存在');
                }

                $score = (new ZccmzjgyxmClient())->getUserConsume($userInfo->phone);
                if ($score['code'] != CodeEnum::SUCCESS) {
                    throw new Exception($score['msg']);
                }

                $score = $score['data']['score'];
                //判断用户积分是否足够
                if ($score < abs($diffAmount)) {
                    throw new Exception('用户积分不足');
                }
            }
        }

        return [
            'estimate_type' => $estimateType,
            'amount' => intval(abs($diffAmount)),
        ];
        */
    }

    public static function handleStatic($orderInfo): int
    {
        $amountUnit = OrderEnum::AMOUNT_UNIT[$orderInfo->amount_type];
        $orderNo = $orderInfo->order_no;
        try {
            //验证订单支付状态
            $needPay = self::_validOrderPayStatus($orderInfo->id);
            if( $needPay !== true ) {
                Log::error(sprintf("订单ID[%d],已经支付过[%d]。", $orderInfo->id, $needPay));
                return 0;
            }

            $payStatus = OrderEnum::PAY_STATUS_SUCCESS;
            // 完成订单支付
            if ($orderInfo->amount_type == OrderEnum::ORDER_PAY_INTEGRAL) {//判断用户积分是否足够
                OrderService::_deductPoint($orderInfo);
                OrderService::_addAmountLogPay($orderInfo, '订单支付-'.$amountUnit.'。');
            } elseif($orderInfo->amount_type == OrderEnum::ORDER_PAY_DIGITAL) {// 扣除钱包 20231026 by LC
                OrderService::_deductDigital($orderInfo);
                OrderService::_addAmountLogPay($orderInfo, '订单支付-'.$amountUnit.'。');
            }elseif($orderInfo->amount_type == OrderEnum::ORDER_PAY_GYCX_AXD) {// 公益出行 积分 20231026 by LC
                $msg = OrderService::_decuteGycxAxd($orderInfo);
                OrderService::_addAmountLogPay($orderInfo, '订单支付-'.$amountUnit.'('.$msg.')。');
            }elseif($orderInfo->amount_type == OrderEnum::ORDER_PAY_ENTERPRISE_COMMUTE_10W) {// 员工通勤 积分 20231123 by LC
                $msg = OrderService::_decuteCommuteAxd($orderInfo);
                OrderService::_addAmountLogPay($orderInfo, '订单支付-'.$amountUnit.'('.$msg.')。');
            }elseif($orderInfo->amount_type == OrderEnum::ORDER_PAY_OFFLINE_PAYMENT) { // 商业订单，线下月结
                OrderService::_addAmountLogPay($orderInfo, '订单支付-'.$amountUnit);
                $payStatus = OrderEnum::PAY_STATUS_OFFLINE;
            }

            $orderInfo->pay_status = $payStatus;
            if(!$orderInfo->save()){
                throw new \Exception('保存订单失败。');
            }
            //============================付款成功的订单 做以下内容========================
            // 创建订单扩展表
            self::_addOrderExtend($orderInfo);
            // 添加 订单中手机号的虚拟号
            self::_addOrderDypls($orderInfo->id, $orderInfo->order_no);

            // 添加订单日志 20230901 by LC
            LogsModel::query()->create([
                'type'      => LogsEnum::LOGS_TYPE_ORDER,
                'ref_id'    => $orderInfo->id,
                'ref_no'  => $orderInfo->order_no,
                'user_id'   => $orderInfo->user_id,
                'user_type' => LogsEnum::LOGS_USER_TYPE_NORMAL,
                'username'  => LogsEnum::LOGS_USER_NAME,
                'content' => '生成订单。',
            ]);
            // 去掉redis缓存 20230926 by LC
            if( $orderInfo->user_id > 0 && $orderInfo->user_id != env('BUSINESS_ORDER_USER_ID',0))
                // 去掉用户订单的缓存 20230926 by LC
                (new RedisKeysService())->deleteOrderListKey($orderInfo->user_id, $orderInfo->driver_id);

        } catch (\Exception|NotFoundExceptionInterface|ContainerExceptionInterface $e) {
            $msg = sprintf('订单[%s]异步支付[%s]失败, E=%s',$orderNo,$amountUnit,$e->getMessage());
            Log::error($msg);
            MonitorService::addOrderCreatedException($msg);

            $orderInfo->pay_status = OrderEnum::PAY_STATUS_FAILED;
            $orderInfo->deleted_at = time();

            if(!$orderInfo->save()){
                throw new \Exception('保存订单失败。');
            }
        }
        return 0;
    }
    private static function _addOrderExtend($orderInfo)
    {
        $orderId = $orderInfo->id;

        $where = [
            'vehicle_type'  => $orderInfo->vehicle_type,
            'use_type'      => $orderInfo->vehicle_use_type,
            'up_stream'     => $orderInfo->platform_id,
            'payment'       => $orderInfo->amount_type,
            'city_code'     => $orderInfo->city_code
        ];
        $fields = ['start_price', 'start_km', 'over_distince_price', 'start_minutes', 'over_time_price'];

        $row = VehicleConfigModel::query()->where($where)->first(array_merge($fields,array_keys($where)));
        if( !empty($row) ) {
            // 记录订单的费用
            OrderExtendModel::query()->create([
                'order_id'      => $orderId,
                'amount_rule'   => json_encode($row->toArray())
            ]);
        }else{
            throw new \Exception(sprintf("订单ID(%d)，找不到对应的金额配置", $orderId));
        }
    }

    /**
     * 标记要处理订单中手机号的虚拟化
     *
     * @param $orderId
     * @param $orderNo
     * @return void
     */
    private static function _addOrderDypls($orderId, $orderNo)
    {
        if( env('ALIYUN_DYPLS_ENABLED',true) )
        {
            // 写入订单的虚拟号
            OrderDyplsModel::query()->create([
                'order_id'=> $orderId,
                'order_no'=> $orderNo,
                'status'    => OrderDyplsEnum::STATUS_UN_USE
            ]);
        }
    }

    /**
     * 验证订单是否需要支付
     *
     * @param $orderId
     * @return mixed|true
     */
    private static function _validOrderPayStatus($orderId)
    {
        $row = OrderModel::query()->find($orderId, ['pay_status'])->toArray();
        if ( in_array($row['pay_status'], [OrderEnum::PAY_STATUS_SUCCESS, OrderEnum::PAY_STATUS_OFFLINE]) ) return $row['pay_status'];
        return true;
    }
}
